﻿using HamcoWcs.Contract.ContractCommon;
using HamcoWcs.Contract.ContractMes;
using HamcoWcs.Contract.ContractPcon.IPconDbMsgParsers;
using HamcoWcs.DAL;
using HamcoWcs.Entitys.SubTasks;
using HamcoWcs.Models.Common.Enums;
using HamcoWcs.Models.DeviceMsgs.SrmMsgs;
using HamcoWcs.Models.Devices;
using HamcoWcs.Models.Exceptions;
using HamcoWcs.Models.TibcoMessage;
using HamcoWcs.Service.Common;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;

namespace HamcoWcs.Service.Srm.SrmTaskParsers
{
    /// <summary>读码异常</summary>
    public class SrmParser_AbnormalRead : SrmParserBase
    {
        public override EnumSrmRequest RequestType => EnumSrmRequest.AbnormalRead;
        private readonly IBaseTaskService _baseTaskService;

        public override void Deal(SrmDto srm, SrmPlc srmPlc)
        {
            // 获取此堆垛机当前的任务
            SubTask task;

            // 读码异常了获取堆垛机当前任务
            task = GetSrmTask(srm);
            // 
            //if (string.IsNullOrEmpty(srm.UnitId) || srm.UnitId.Equals("NoRead", StringComparison.OrdinalIgnoreCase))
            //{

            //}
            //else
            //{
            //    task = GetTargetTask(srm);
            //}
            if (task == null)
            {
                _logger.AddWcsRunLog(task.UnitId, $"读码异常时未找到{srm.MachineName}-{srm.PortName}正在执行的任务,处理读码异常失败");
                return;
            }

            var emptyloc = _locationService.GetEmptyLocationBySrm(srm.SrmName);

            if (emptyloc is null)
            {
                throw new SrmNotFoundEmptyException();
            }

            var readType = "";

            if (string.IsNullOrEmpty(srm.UnitId) || srm.UnitId.Equals("NoRead", StringComparison.OrdinalIgnoreCase))
            {
                // 没有读到码
                readType = "NoRead";
                _logger.AddWcsRunLog(task.UnitId, $"[{readType}][{srm.DeviceName}]{task.MainTask.TaskId}读码异常,old:{task.UnitId}");
            }
            else
            {
                // 与下发条码不匹配
                readType = "Mismatch";
                _logger.AddWcsRunLog(task.UnitId, $"[{readType}][{srm.DeviceName}]{task.MainTask.TaskId}读码异常,old:{task.UnitId},new:{srm.UnitId}");
            }
            //_logger.AddSystemErrorLog($"SrmParser->AbnormalRead:Warning,{srm.MachineName}-{srm.PortName}在{subTaskType}上报了读码异常");
            var subTaskType = Enum.Parse<EnumSubTaskType>(task.SubTaskType);
            switch (subTaskType)
            {
                case EnumSubTaskType.PconTask:
                case EnumSubTaskType.SrmAbnormalInboundTask: return;
                case EnumSubTaskType.SrmInventoryTask:
                    var loc = _locationService.GetLocationByWcsName(task.ToLoc);
                    loc.Remark = "盘点时读码异常";
                    _baseTaskService.UpdateSubTaskStatus(task.Id, EnumSubTaskStatus.Finished);
                    return;
                default:
                    break;
            }


            // 起始地为货位：先清空起始地货位数据
            if (task.FromLoc.IsShelf())
            {
                var loc = _locationService.GetLocationByWcsName(task.FromLoc);

                if (loc.UnitId == task.UnitId)
                {
                    if (loc.ZoneName.Contains("Z6"))
                    {
                        loc.LocStatus = (int)EnumLocStatus.HandOff;
                    }
                    else
                    {
                        loc.LocStatus = (int)EnumLocStatus.Empty;
                    }
                    loc.Remark = "";
                    loc.UnitId = "";
                    _wcsDbContext.SaveChanges();
                }
             
            }

            // 目的地为货位：清空目的地货位数据
            if (task.ToLoc.IsShelf())
            {
                if (subTaskType != EnumSubTaskType.SrmInventoryTask)
                {
                    var loc = _locationService.GetLocationByWcsName(task.ToLoc);

                    if (loc.ZoneName.Contains("Z6"))
                    {
                        loc.LocStatus = (int)EnumLocStatus.HandOff;
                    }
                    else
                    {
                        loc.LocStatus = (int)EnumLocStatus.Empty;
                    }
                    loc.Remark = "";
                    _wcsDbContext.SaveChanges();
                }
            }

            // 需要中转,清空中转货位信息
            if (task.IsNeedSection)
            {
                var temploc = _locationService.GetLocationByWcsName(task.HandOffShelf);
                if (temploc != null)
                {
                    temploc.LocStatus = 4;
                    temploc.Remark = "";
                    _wcsDbContext.SaveChanges();
                }
                task.IsNeedSection = false;
                task.HandOffShelf = "";
            }
            task.SubTaskType = EnumSubTaskType.SrmAbnormalInboundTask.ToString();
            emptyloc.LocStatus = (int)EnumLocStatus.In;
            if (readType == "NoRead")
            {
                emptyloc.Remark = $"[{DateTime.Now:yyyyMMddHHmmss}]-[{task.MainTask.TaskId}]-[{readType}]-[{srm.MachineName}-{srm.PortName}]";
            }
            else
            {
                emptyloc.Remark = $"[{DateTime.Now:yyyyMMddHHmmss}]-[{task.MainTask.TaskId}]-[{readType}]-[{srm.MachineName}-{srm.PortName}],new is {srm.UnitId}";
            }
            //emptyloc.Remark = $"{DateTime.Now:yyyyMMddHHmmss}-[{readType}]-[{srm.MachineName}-{srm.PortName}],new is {srm.UnitId}";
            emptyloc.IsLock = true;
            //emptyloc.UnitId = "";
            task.ToLoc = emptyloc.WcsLocName;
            _wcsDbContext.SaveChanges();
        }


        public SrmParser_AbnormalRead(IBaseTaskService baseTaskService, ILocationService locationService, WcsDbContext wcsDbContext,
            IMesCommunicateService mesCommunicateService, ILoggerService logger)
            : base(wcsDbContext, locationService, mesCommunicateService, logger)
        {
            _baseTaskService = baseTaskService;
        }

        protected override SubTask GetTargetTask(SrmDto srm)
        {
            return _wcsDbContext.SubTasks
                                .Where(x => x.TaskStatus == EnumSubTaskStatus.OnProgress.ToString())
                                .Where(x => x.PlcName == srm.SrmName)
                                .Include(x => x.MainTask)
                                .FirstOrDefault();
        }
    }
}
